#ifdef __cplusplus
extern "C" {
#endif
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#ifdef __cplusplus
}
#endif

// #define WEBP_DIRECTLY
#define CODEC_LOG

enum CodecType{ENCODER, DECODER};

class Codec
{
public:
	FILE* f;
	Codec(){
		#ifdef CODEC_LOG
		f = fopen("codec.log", "w");
		#endif
	}

	~Codec(){fclose(f);}


	/**
	 * @imgData: A reference of data to encode.
	 * @pktData: A reference of data encoded will be returned.
	 * @output: size on success, -1 on error.
	 */
	virtual int encode(byte* imgData, byte* pktData) = 0;

	/**
	 * @pktData: A reference of data received to decode.
	 * @pktSize: Size of packet data.
	 * @imgData: A reference of data decoded will be returned.
	 */
	virtual int decode(byte* pktData, int pktSize, byte* imgData) = 0;
};

class FFMPEGCodec : public Codec
{
	static bool registered;
	bool _x264rgb;
	AVCodecContext *pCodecCtx;
	SwsContext* convertCtx;
	AVFrame *rgbFrame;
	AVFrame *yuvFrame;
	int64_t pts;

	void initEncoder();
	void initDecoder();

public:
	FFMPEGCodec(CodecType type, bool x264rgb);
	
	int encode(byte* imgData, byte* pktData);
	int decode(byte* pktData, int pktSize, byte* imgData);
};

class WebPCodec : public Codec
{
	int64_t pts;

public:
    WebPCodec(){pts = 0;};

    int encode(byte* imgData, byte* pktData);
	int decode(byte* pktData, int pktSize, byte* imgData);
};